﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Windows.Forms;
using DevelopersToolbox;

namespace NetworkTools {
    public partial class NetworkInfoControl : UserControl, IExecutableTool {
        private bool _firstTime = true;

        public NetworkInfoControl() {
            InitializeComponent();
        }

        public void Execute() {
            bool first = true;
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<style>");
            sb.AppendLine("h1 {");
            sb.AppendLine("  font-size: 15pt;");
            sb.AppendLine("  padding: 0;");
            sb.AppendLine("  margin: 0;");
            sb.AppendLine("}");
            sb.AppendLine("table {");
            sb.AppendLine("  margin-left: 3em;");
            sb.AppendLine("}");
            sb.AppendLine("table tr th {");
            sb.AppendLine("  text-align: right;");
            sb.AppendLine("}");
            sb.AppendLine("</style>");

            foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces()) {
                if (!first) {
                    sb.AppendLine("<hr/>");
                }
                sb.AppendLine(string.Format("<h1>{0}</h1>", networkInterface.Name));

                IPInterfaceProperties ipProperties = networkInterface.GetIPProperties();
                //IPv4InterfaceProperties ipv4Properties = ipProperties.GetIPv4Properties();
                //IPv6InterfaceProperties ipv6Properties = ipProperties.GetIPv6Properties();

                sb.AppendLine("<table>");
                sb.AppendLine(string.Format("  <tr><th>Description:</th><td>{0}</td></tr>", networkInterface.Description));
                sb.AppendLine(string.Format("  <tr><th>Type:</th><td>{0} {1}</td></tr>", networkInterface.NetworkInterfaceType, SpeedToString(networkInterface.Speed)));
                sb.AppendLine(string.Format("  <tr><th>Status:</th><td>{0}</td></tr>", networkInterface.OperationalStatus));
                sb.AppendLine(string.Format("  <tr><th>MAC:</th><td>{0}</td></tr>", PhysicalAddresstoString(networkInterface.GetPhysicalAddress())));
                sb.AppendLine(string.Format("  <tr><th>IP Addresses:</th><td>{0}</td></tr>", IpAddressToString(ipProperties.UnicastAddresses)));
                sb.AppendLine(string.Format("  <tr><th>Gateway:</th><td>{0}</td></tr>", IpAddressToString(ipProperties.GatewayAddresses)));
                sb.AppendLine(string.Format("  <tr><th>DNS Servers:</th><td>{0}</td></tr>", IpAddressToString(ipProperties.DnsAddresses)));
                sb.AppendLine("</table>");
                first = false;
            }
            _info.DocumentText = sb.ToString();
        }

        private object IpAddressToString(IEnumerable<IPAddress> addresses) {
            StringBuilder sb = new StringBuilder();
            foreach (IPAddress address in addresses) {
                sb.AppendLine(string.Format("{0}<br/>", address));
            }
            return sb.ToString();
        }

        private object IpAddressToString(IEnumerable<GatewayIPAddressInformation> addresses) {
            StringBuilder sb = new StringBuilder();
            foreach (GatewayIPAddressInformation address in addresses) {
                sb.AppendLine(string.Format("{0}<br/>", address.Address));
            }
            return sb.ToString();
        }

        private string IpAddressToString(IEnumerable<UnicastIPAddressInformation> addresses) {
            StringBuilder sb = new StringBuilder();
            foreach (UnicastIPAddressInformation address in addresses) {
                sb.AppendLine(string.Format("{0}<br/>", address.Address));
            }
            return sb.ToString();
        }

        private string PhysicalAddresstoString(PhysicalAddress address) {
            StringBuilder sb = new StringBuilder();
            bool first = true;
            foreach (byte b in address.GetAddressBytes()) {
                if (!first) {
                    sb.Append("-");
                }
                if (b < 10) {
                    sb.Append("0");
                }
                sb.Append(Convert.ToString(b, 16));
                first = false;
            }
            return sb.ToString().ToUpper();
        }

        private string SpeedToString(long speed) {
            if (speed >= 1000000000) {
                double d = (double)speed / 1000000000;
                return d.ToString("0.##Gb");
            } else {
                double d = (double)speed / 1000000;
                return d.ToString("0.##Mb");
            }
        }

        private void _refresh_Click(object sender, System.EventArgs e) {
            Execute();
        }

        private void NetworkInfoControl_Paint(object sender, PaintEventArgs e) {
            if (_firstTime) {
                Execute();
                _firstTime = false;
            }
        }
    }
}
